package com.zenithmind.user.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.user.mapper.RoleMapper;
import com.zenithmind.user.pojo.domain.Permission;
import com.zenithmind.user.pojo.domain.Role;
import com.zenithmind.user.pojo.domain.RolePermission;
import com.zenithmind.user.pojo.query.RoleQuery;
import com.zenithmind.user.pojo.vo.RoleVO;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.user.service.PermissionService;
import com.zenithmind.user.service.RolePermissionService;
import com.zenithmind.user.service.RoleService;
import com.zenithmind.common.annotation.DataCache;
import com.zenithmind.common.annotation.DataCacheEvict;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private RolePermissionService rolePermissionService;

    @Autowired
    private PermissionService permissionService;

    /**
     * 分页查询角色信息
     *
     * @param roleQuery 角色查询对象，包含查询参数和分页信息
     * @return 返回分页查询结果，包含角色列表和分页相关数据
     */
    @Override
    @DataCache(prefix = "role:page", key = "#roleQuery.toString()", expireTime = 1800)
    public PageResult<RoleVO> page(RoleQuery roleQuery) {
        Page<Role> page = roleQuery.toPage();

        Page<Role> rolePage = lambdaQuery()
                .like(StringUtils.isNotBlank(roleQuery.getRoleName()), Role::getRoleName, roleQuery.getRoleName())
                .like(StringUtils.isNotBlank(roleQuery.getRoleCode()), Role::getRoleCode, roleQuery.getRoleCode())
                .eq(roleQuery.getStatus() != null, Role::getStatus, roleQuery.getStatus())
                .orderByDesc(Role::getUpdateTime)
                .page(page);

        // 获取角色权限
        List<RolePermission> rolePermissions = rolePermissionService.list(new LambdaQueryWrapper<RolePermission>()
                .in(RolePermission::getRoleId, rolePage.getRecords().stream().map(Role::getId).collect(Collectors.toList())));

        // 

        // 将角色权限分配给角色并转换为VO对象
        List<RoleVO> roleVOList = rolePage.getRecords().stream().map(role -> {
            RoleVO roleVO = new RoleVO();
            BeanUtils.copyProperties(role, roleVO);

            // 填充权限字段
            List<Permission> permissions = rolePermissions.stream()
                    .filter(rp -> rp.getRoleId().equals(role.getId()))
                    .map(rp -> permissionService.getById(rp.getPermissionId()))
                    .collect(Collectors.toList());

            roleVO.setPermissions(permissions);
            return roleVO;
        }).collect(Collectors.toList());


        return new PageResult<>(roleVOList, rolePage.getTotal(), rolePage.getCurrent(), rolePage.getSize());
    }

    /**
     * 分配角色权限
     *
     * @param rolePermission 角色权限对象，包含角色ID和权限ID列表
     * @throws RuntimeException 如果角色ID为空，则抛出运行时异常
     */
    @Override
    @Transactional
    @DataCacheEvict(prefix = "role", allEntries = true)
    public void assignPermission(RolePermission rolePermission) {
        if (StringUtils.isBlank(rolePermission.getRoleId())) {
            throw new RuntimeException("角色ID不能为空");
        }

        // 添加权限
        rolePermissionService.save(rolePermission);
    }

    /**
     * 根据ID获取角色信息和权限
     *
     * @param id 角色ID
     * @return 返回角色信息对象，包含角色基本信息和权限列表
     * @throws RuntimeException 如果角色ID为空或角色不存在，则抛出运行时异常
     */
    @Override
    @DataCache(prefix = "role", key = "#id", expireTime = 3600)
    public RoleVO getRoleById(String id) {
        if (StringUtils.isBlank(id)) {
            throw new RuntimeException("角色ID不能为空");
        }

        // 获取角色信息
        Role role = getById(id);
        if (role == null) {
            throw new RuntimeException("角色不存在");
        }

        RoleVO roleVO = new RoleVO();
        BeanUtils.copyProperties(role, roleVO);

        // 获取角色权限
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, id);
        List<RolePermission> rolePermissions = rolePermissionService.list(wrapper);

        if (rolePermissions != null && !rolePermissions.isEmpty()) {
            List<String> permissionIds = rolePermissions.stream()
                    .map(RolePermission::getPermissionId)
                    .collect(Collectors.toList());

            List<Permission> permissions = permissionService.listByIds(permissionIds);
            roleVO.setPermissions(permissions);
        }

        return roleVO;
    }

    /**
     * 获取所有角色信息
     *
     * @return 返回角色信息列表
     */
    @Override
    @DataCache(prefix = "role:all", expireTime = 3600)
    public List<RoleVO> listRoles() {
        // 获取所有角色
        List<Role> roles = list();

        // 转换为VO对象
        return roles.stream().map(role -> {
            RoleVO roleVO = new RoleVO();
            BeanUtils.copyProperties(role, roleVO);
            return roleVO;
        }).collect(Collectors.toList());
    }
    
    /**
     * 批量分配权限给角色
     *
     * @param roleId 角色ID
     * @param permissionIds 权限ID列表
     * @throws RuntimeException 如果角色ID为空，则抛出运行时异常
     */
    @Override
    @Transactional
    @DataCacheEvict(prefix = "role", allEntries = true)
    public void assignBatchPermissions(String roleId, List<String> permissionIds) {
        if (StringUtils.isBlank(roleId)) {
            throw new RuntimeException("角色ID不能为空");
        }
        
        if (permissionIds == null || permissionIds.isEmpty()) {
            throw new RuntimeException("权限ID列表不能为空");
        }
        
        // 先删除原有权限
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, roleId);
        rolePermissionService.remove(wrapper);
        
        // 批量添加新权限
        List<RolePermission> rolePermissions = new ArrayList<>();
        for (String permissionId : permissionIds) {
            RolePermission rolePermission = new RolePermission();
            rolePermission.setRoleId(roleId);
            rolePermission.setPermissionId(permissionId);
            rolePermissions.add(rolePermission);
        }
        
        rolePermissionService.saveBatch(rolePermissions);
    }
    
    /**
     * 获取角色的权限ID列表
     *
     * @param roleId 角色ID
     * @return 角色拥有的权限ID列表
     */
    @Override
    @DataCache(prefix = "role:permissions", key = "#roleId", expireTime = 3600)
    public List<String> getRolePermissionIds(String roleId) {
        if (StringUtils.isBlank(roleId)) {
            throw new RuntimeException("角色ID不能为空");
        }
        
        // 查询角色权限关联
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, roleId);
        List<RolePermission> rolePermissions = rolePermissionService.list(wrapper);
        
        // 提取权限ID
        return rolePermissions.stream()
            .map(RolePermission::getPermissionId)
            .collect(Collectors.toList());
    }
    
    /**
     * 添加或更新角色
     *
     * @param role 角色对象
     * @return 是否成功
     */
    @DataCacheEvict(prefix = "role", allEntries = true)
    public boolean saveOrUpdateRole(Role role) {
        return saveOrUpdate(role);
    }

    /**
     * 删除角色
     *
     * @param id 角色ID
     * @return 是否成功
     */
    @Transactional
    @DataCacheEvict(prefix = "role", allEntries = true)
    public boolean removeRole(String id) {
        // 先删除角色关联的权限
        LambdaQueryWrapper<RolePermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RolePermission::getRoleId, id);
        rolePermissionService.remove(wrapper);
        
        // 再删除角色
        return removeById(id);
    }
}
